﻿#include "imageProcessing.h"

struct rgb24
{
    uint8_t b;
    uint8_t g;
    uint8_t r;
};


bool ImageToGray::redChannel(QImage &image)
{
    int width = image.width();
    int height = image.height();
    switch (image.format())
    {
    case QImage::Format_RGB32:
    case QImage::Format_ARGB32:
    case QImage::Format_ARGB32_Premultiplied:
        for(int i = 0; i < height ; i++)
        {
            QRgb * line1 = (QRgb *) image.scanLine(i);
            for(int j = 0; j < width; j ++)
            {
                int r = qRed(line1[j]);
                line1[j] =qRgb(r, 0, 0) ;
            }
        }
        return true;
        break;
    case QImage::Format_RGB888:
        for(int i = 0; i < height ; i++)
        {
            rgb24 * line1 = (rgb24 *) image.scanLine(i);
            for(int j = 0; j < width; j ++)
            {
                line1[j].g = 0;
                line1[j].b = 0;
            }
        }
        return true;
        break;
    default:
        return false;
        break;
    }
}
bool ImageToGray::blueChannel(QImage &image)
{

    int width = image.width();
    int height = image.height();
    switch (image.format())
    {
    case QImage::Format_RGB32:
    case QImage::Format_ARGB32:
    case QImage::Format_ARGB32_Premultiplied:
        for(int i = 0; i < height ; i++)
        {
            QRgb * line1 = (QRgb *) image.scanLine(i);
            for(int j = 0; j < width; j ++)
            {
                int b = qBlue(line1[j]);
                line1[j] =qRgb(0, 0, b) ;
            }
        }
        return true;
        break;
    case QImage::Format_RGB888:
        for(int i = 0; i < height ; i++)
        {
            rgb24 * line1 = (rgb24 *) image.scanLine(i);
            for(int j = 0; j < width; j ++)
            {
                line1[j].r = 0;
                line1[j].g = 0;
            }
        }
        return true;
        break;
    default:
        return false;
        break;
    }
}
bool ImageToGray::greenChannel(QImage &image)
{

    int width = image.width();
    int height = image.height();
    switch (image.format())
    {
    case QImage::Format_RGB32:
    case QImage::Format_ARGB32:
    case QImage::Format_ARGB32_Premultiplied:
        for(int i = 0; i < height ; i++)
        {
            QRgb * line1 = (QRgb *) image.scanLine(i);
            for(int j = 0; j < width; j ++)
            {
                int g = qGreen(line1[j]);
                line1[j] =qRgb(0, g, 0) ;
            }
        }
        return true;
        break;
    case QImage::Format_RGB888:
        for(int i = 0; i < height ; i++)
        {
            rgb24 * line1 = (rgb24 *) image.scanLine(i);
            for(int j = 0; j < width; j ++)
            {
                line1[j].r = 0;
                line1[j].b = 0;
            }
        }
        return true;
        break;
    default:
        return false;
        break;
    }
}

bool ImageToGray::apply(QImage &image)
{
    switch (image.format())
    {
    case QImage::Format_RGB32:
    case QImage::Format_ARGB32:
    case QImage::Format_ARGB32_Premultiplied:
        RGB32toGray(image);
        return true;
        break;
    case QImage::Format_RGB888:
        RGB888ToGray(image);
        return true;
        break;
    default:
        return false;
        break;
    }
}

ImageToGray::ImageToGray()
{
}

void ImageToGray::ARGB32toGray(QImage &image)
{
    int width = image.width();
    int height = image.height();
    for(int i = 0; i < height ; i++)
    {
        QRgb * line1 = (QRgb *) image.scanLine(i);
        for(int j = 0; j < width; j ++)
        {
            int g = qGray(line1[j]);
            line1[j] =qRgba(g, g, g, 255) ;
        }
    }
}

void ImageToGray::RGB32toGray(QImage &image)
{
    int width = image.width();
    int height = image.height();
    for(int i = 0; i < height ; i++)
    {
        QRgb * line1 = (QRgb *) image.scanLine(i);
        for(int j = 0; j < width; j ++)
        {
            int g = qGray(line1[j]);
            line1[j] =qRgb(g, g, g) ;
        }
    }
}

void ImageToGray::RGB888ToGray(QImage &image)
{
    int width = image.width();
    int height = image.height();
    for(int i = 0; i < height ; i++)
    {
        rgb24 * line1 = (rgb24 *) image.scanLine(i);
        for(int j = 0; j < width; j ++)
        {
            int gray = qGray(line1[j].r, line1[j].g, line1[j].b);
            line1[j].r = gray;
            line1[j].g = gray;
            line1[j].b = gray;
        }
    }
}

bool ImageFlip::apply(QImage &image)
{
    switch (image.format())
    {
    case QImage::Format_RGB32:
    case QImage::Format_ARGB32:
    case QImage::Format_ARGB32_Premultiplied:
        RGB32Flip(image);
        return true;
        break;
    case QImage::Format_RGB888:
        RGB888Flip(image);
        return true;
        break;
    default:
        return false;
        break;
    }
}

void ImageFlip::RGB32Flip(QImage &image)
{
    int width = image.width();
    int height = image.height();
    switch (m_flipMode)
    {
    case BOTH:
        for(int i = 0; i < height / 2; i++)
        {
            QRgb * line1 = (QRgb *) image.scanLine(i);
            QRgb * line2 = (QRgb *) image.scanLine(height - i - 1);
            for(int j = 0; j < width; j ++)
            {
                std::swap(line1[j], line2[width - j - 1]);
            }
        }
        break;
    case HORIZONTAL_FLIP:
        for(int i = 0; i < height; i++)
        {
            QRgb * line = (QRgb *) image.scanLine(i);
            for(int j = 0; j < width / 2; j ++)
            {
                std::swap(line[j], line[width - j - 1]);
            }
        }
        break;
    case VERTICAL_FLIP:
        for(int i = 0; i < height / 2; i++)
        {
            QRgb * line1 = (QRgb *) image.scanLine(i);
            QRgb * line2 = (QRgb *) image.scanLine(height - i - 1);
            for(int j = 0; j < width; j ++)
            {
                std::swap(line1[j], line2[j]);
            }
        }
        break;
    default:
        break;
    }
}

void ImageFlip::RGB888Flip(QImage &image)
{
    int width = image.width();
    int height = image.height();
    switch (m_flipMode)
    {
    case BOTH:
        for(int i = 0; i < height / 2; i++)
        {
            rgb24 * line1 = (rgb24 *) image.scanLine(i);
            rgb24 * line2 = (rgb24 *) image.scanLine(height - i - 1);
            for(int j = 0; j < width; j ++)
            {
                std::swap(line1[j], line2[width - j - 1]);
            }
        }
        break;
    case HORIZONTAL_FLIP:
        for(int i = 0; i < height; i++)
        {
            rgb24 * line = (rgb24 *) image.scanLine(i);
            for(int j = 0; j < width / 2; j ++)
            {
                std::swap(line[j], line[width - j - 1]);
            }
        }
        break;
    case VERTICAL_FLIP:
        for(int i = 0; i < height / 2; i++)
        {
            rgb24 * line1 = (rgb24 *) image.scanLine(i);
            rgb24 * line2 = (rgb24 *) image.scanLine(height - i - 1);
            for(int j = 0; j < width; j ++)
            {
                std::swap(line1[j], line2[j]);
            }
        }
        break;
    default:
        break;
    }
}
